#include<iostream>
#include<coroutine>
#include<exception>
class Awaiter{
    int m_val;
    public:
    Awaiter(int val):m_val(val){

    }
    bool await_ready(){
        return false;
    }
    void await_suspend(std::coroutine_handle<> handle){
        std::cout<<"协程挂起"<<m_val<<std::endl;
    }

    void await_resume(){
        std::cout<<"协程回复"<<std::endl;
    }
    int getVal(){
        return m_val;
    }
    
    
};

struct Result{
    public:
    int start,end;
    struct promise_type{
        int val;
        bool is_ready = false;
        Result get_return_object(){
            return Result(std::coroutine_handle<promise_type>::from_promise(*this));
        }
        // std::suspend_always await_transform(int value){
        //     val = value;
        //     is_ready = true;
        //     return {};
        // }
        std::suspend_always initial_suspend(){
            return {};
        }
        // std::suspend_always await_transform(Awaiter a){
        //     val = a.getVal();
        //     return {};
        // }
        std::suspend_always final_suspend() noexcept{
            return {};
        }
        void unhandled_exception(){}

        void return_void(){}

    };
    Result(std::coroutine_handle<promise_type> corout):handle(corout){}
    bool hasnext(){
        if(handle.done()){
            return false;
        }
        if(!handle.promise().is_ready){
            handle.resume();
        }
        if(handle.done()){
            return false;
        }else{
            return true;
        }
    }
    std::coroutine_handle<promise_type> handle;
        int next(){
            if(hasnext()){
                handle.promise().is_ready=false;
                return handle.promise().val;
            }
            throw -1;
        }
    ~Result(){
        handle.destroy();
    }
};
Result cofunction(int start,int end){
    if(start>end) throw std::runtime_error("start 应当小于end");
    for(int i=start;i<end;++i){
        co_await Awaiter{i};
    }

}

int main(){
    auto co = cofunction(1,10);
    for(int i=1;i<10;i++){
        std::cout<<co.next()<<std::endl;
    }
}
